import typeOfUtils from "./type-of-utils";

const defaultConfig = {
    decimal: 2
}

export default class NumberUtils {

    /**
     * 转成整型
     * @param num
     * @return {number}
     */
    static toInt(num) {
        num = parseInt(String(num))
        if (typeOfUtils.isEmpty(num)) {
            return 0
        }
        return num
    }

    /**
     *
     * @param num
     * @return {string}
     */
    static toStringInt(num) {
        num = NumberUtils.toInt(num)
        return String(num)
    }

    static toFloat(num) {
        num = parseFloat(String(num))
        if (typeOfUtils.isEmpty(num)) {
            return 0
        }
        return num
    }

    static toStringFloat(num) {
        num = NumberUtils.toFloat(num)
        return String(num)
    }

    /**
     * 转成数字
     * @param nums
     * @return {number[]}
     */
    static numsToNumbers(nums = []) {
        return nums.map(i => {
            return NumberUtils.toFloat(i)
        })
    }

    /**
     * 相加
     * @param nums
     * @return {number}
     */
    static add(nums = []) {
        let sum = 0
        NumberUtils.numsToNumbers(nums).forEach(i => {
            sum += i
        })
        return sum
    }

    /**
     * 相加四舍五入
     * @param nums
     * @param decimal 保留的小数位数
     * @return {string}
     */
    static addRounding(nums = [], decimal = defaultConfig.decimal) {
        const number = NumberUtils.add(nums);
        return NumberUtils.numDecimalNotZeroForLast(number.toFixed(decimal))
    }

    /**
     * 相加不四舍五入
     * @param nums
     * @param decimal
     * @return {string}
     */
    static addNotRounding(nums = [], decimal = defaultConfig.decimal) {
        const number = NumberUtils.add(nums);
        return NumberUtils.numDecimalNotZeroForLast(NumberUtils.notRounding(number, decimal))
    }

    /**
     * 不要四舍五入
     * @param num
     * @param decimal
     * @return {string}
     */
    static notRounding(num, decimal = defaultConfig.decimal) {
        const strNumber = String(num)
        const strings = strNumber.split('.');
        if (decimal >= strings[1].length) {
            return strings.join('.')
        } else {
            return strings[0] + '.' + strings[1].substring(0, decimal + 1)
        }
    }

    /**
     * 不要数字小数后面的0
     * @param num
     * @return {string}
     */
    static numDecimalNotZeroForLast(num) {
        return String(Number(num))
    }

    /**
     * 乘法
     * @param nums
     * @return {number}
     */
    static mul(nums = []) {
        let mul = 1
        NumberUtils.numsToNumbers(nums).forEach(i => {
            mul *= i
        })
        return mul
    }

    /**
     * 乘法四舍五入
     * @param nums
     * @param decimal
     * @return {string}
     */
    static mulRounding(nums = [], decimal = defaultConfig.decimal) {
        const number = NumberUtils.mul(nums);
        return NumberUtils.numDecimalNotZeroForLast(number.toFixed(decimal))
    }

    /**
     * 乘法不四舍五入
     * @param nums
     * @param decimal
     * @return {string}
     */
    static mulNotRounding(nums = [], decimal = defaultConfig.decimal) {
        const number = NumberUtils.mul(nums)
        return NumberUtils.numDecimalNotZeroForLast(NumberUtils.notRounding(number, decimal))
    }

    /**
     * 最大最小值范围值限制
     * @param num
     * @param min
     * @param max
     * @return {string}
     */
    static numLimitMinAndMax(num, min = 0, max = 0) {
        const number = NumberUtils.numsToNumbers([num])[0]
        let result = number
        if (number < min) {
            result = min
        }
        if (number > max) {
            result = max
        }
        return String(result)
    }

    /**
     * 除法
     * @param nums
     * @return {number}
     */
    static div(nums = []) {
        const numbers = NumberUtils.numsToNumbers(nums)
            .filter(i => i !== 0)
        if (typeOfUtils.isEmpty(numbers)) {
            return 0
        }
        if (numbers.length === 1) {
            return 0
        }
        let div = numbers[0]
        for (let i = 1; i < numbers.length; i++) {
            div /= numbers[i]
        }
        return div;
    }

    /**
     * 除法四舍五入
     * @param nums
     * @param decimal
     * @return {string}
     */
    static divRounding(nums = [], decimal = defaultConfig.decimal) {
        const number = NumberUtils.div(nums);
        return NumberUtils.numDecimalNotZeroForLast(number.toFixed(decimal))
    }

    /**
     * 除法不四舍五入
     * @param nums
     * @param decimal
     * @return {string}
     */
    static divNotRounding(nums = [], decimal = defaultConfig.decimal) {
        const number = NumberUtils.div(nums)
        return NumberUtils.numDecimalNotZeroForLast(NumberUtils.notRounding(number, decimal))
    }

    /**
     * 值是否在范围内
     * @param num
     * @param min
     * @param max
     * @return {boolean}
     */
    static isNumLimitMinAndMax(num, min, max) {
        const result = NumberUtils.numLimitMinAndMax(num, min, max);
        return result === String(num);
    }

    /**
     * 判断两个数是否相等
     * @param num1
     * @param num2
     * @param offset 可接收偏移量
     * @return {boolean}
     */
    static isEqual(num1, num2, offset = 0.1) {
        num1 = NumberUtils.numsToNumbers([num1])[0]
        num2 = NumberUtils.numsToNumbers([num2])[0]
        return Math.abs(num1 - num2) <= offset;
    }
}